package com.fanshuai.tree.trie.pinyin;

import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * 拼音工具类
 */
public class PinyinUtil {
    private static final HanyuPinyinOutputFormat format;
    static {
        format = new HanyuPinyinOutputFormat();
        format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
        format.setVCharType(HanyuPinyinVCharType.WITH_V);
        format.setCaseType(HanyuPinyinCaseType.LOWERCASE);
    }

    /**
     * 将文本转为拼音  返回每个拼音字符和在原文中的位置
     * @param text
     * @return
     */
    public static List<PinyinIndex> getPinyinIndex(String text) {
        if (StringUtils.isBlank(text)) {
            return new ArrayList<>();
        }

        List<PinyinIndex> indices = new ArrayList<>();

        for (int i = 0; i < text.length(); i++) {
            char ch = text.charAt(i);
            if (Character.isWhitespace(ch)) {
                continue;
            }
            if (isEnglishWord(ch)) {
                PinyinIndex index = new PinyinIndex(ch, i);
                indices.add(index);
                continue;
            }

            try {
                String[] pinyinArr = PinyinHelper.toHanyuPinyinStringArray(ch, format);
                if (null != pinyinArr && pinyinArr.length > 0) {
                    String pinyin = pinyinArr[0];
                    for (char c : pinyin.toCharArray()) {
                        PinyinIndex index = new PinyinIndex(c, i);
                        indices.add(index);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return indices;
    }

    /**
     * 返回拼音文本
     * @param indices
     * @return
     */
    public static String getPinyin(List<PinyinIndex> indices) {
        if (CollectionUtils.isEmpty(indices)) {
            return null;
        }
        StringBuilder b = new StringBuilder();
        for (PinyinIndex index : indices) {
            b.append(index.ch);
        }

        return b.toString();
    }

    private static boolean isEnglishWord(char ch) {
        boolean letter = ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z';
        boolean numeric = ch >= '0' && ch <= '9';
        boolean underline = ch == '_';

        return letter || numeric || underline;
    }

    /**
     * 直接获取拼音文本
     * @param text
     * @return
     */
    public static String getPinyinText(String text) {
        if (StringUtils.isBlank(text)) {
            return "";
        }

        StringBuilder b = new StringBuilder();

        for (int i = 0; i < text.length(); i++) {
            char ch = text.charAt(i);
            if (Character.isWhitespace(ch)) {
                continue;
            }
            if (isEnglishWord(ch)) {
                b.append(ch);
                continue;
            }

            try {
                String[] pinyinArr = PinyinHelper.toHanyuPinyinStringArray(ch, format);
                if (null != pinyinArr && pinyinArr.length > 0) {
                    String pinyin = pinyinArr[0];
                    b.append(pinyin);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return b.toString();
    }
}
